
//SUPPORT FUNCTIONS.

//ugly but pretty robust tracer
target.trace = function(message)
{
    //is logging enabled?
    if(!this.enableLogging)
	    return;
    if (!this.hasOwnProperty('logno'))
        this.logno = 0;
    if (!this.hasOwnProperty('driveroot'))
        this.driveroot = 'b:';
    this.stringToFile(this.driveroot+"/autorun_log2."+this.logno, message);
    this.logno++;
}

//a not very robust copying function. groks a:/ and b:/
target.copyFile = function(from,to)
{
    //this.trace("copyFile() from "+from+" to "+to+"\n");
    try {
      FileSystem.copyFile(from, to);
    }
    catch(e) {
      this.trace("copy error: "+e.message+"\n");
      this.statusLine.setValue("copy error: "+e.message);
      return false;
    }
    if (FileSystem.getFileInfo(to))
      return true;
    else
      return false;
}

//load an VM from xml. mainly intended to load extenstions
target.loadVm = function(path)
{
//    this.trace("loading vm from "+path+"\n");
    var myvm = FskInclude.load(path);
//    this.trace("myvm = "+myvm+"\n");
//    this.trace(myvm.serialize()+"\n");
    try {
      var t = myvm.load();
    }
    catch(e)
    {
      this.trace("vm load error: "+e.toString()+"\n");
      this.statusLine.setValue("vm load error: "+e.toString());
    }
}

//return file's content in a string
target.fileToString = function(path)
{
  var res=null;
  try {
    var f = new Stream.File(path)
    res = f.toString();
  }
  catch (e)
  {
    res=null;
  }
  return res;
}

//write string to file, overwriting if needed
target.stringToFile = function(path, text)
{
  try {
    if (FileSystem.getFileInfo(path))
   	   FileSystem.deleteFile(path);
  	var stream = new Stream.File(path, 1);
  	stream.writeString(text);
  	stream.close();
  }
  catch (e)
  {
	  this.statusLine.setValue("Error writing string to file " + path);
  }
}

target.scriptPrepared = false;
target.prepareScript = function()
{
  if (!this.scriptPrepared)
  {
    if (!this.copyFile(this.driveroot+"/libfskLoad.so","/tmp/libfskLoad.so")) {
	this.statusLine.setValue("Error copying library libfskLoad.so");
        return false;
    }
    this.stringToFile("/tmp/cardroot", this.driveroot);
    this.scriptPrepared = true;
  }
  return this.scriptPrepared;
}

//run /tmp/script.sh
target.runScript = function()
{
  if (this.prepareScript())
    this.loadVm(this.driveroot+"/myvm2.xml");
}

//put text into /tmp/script.sh and run it
target.runCommand = function(text)
{
  var header = "#!/bin/sh\n"+
  "PATH=\"/usr/local/bin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/games:/usr/local/sony/bin:/usr/sbin\"\n"+
  "LD_LIBRARY_PATH=\"/opt/sony/ebook/application:/lib:/usr/lib:/usr/local/sony/lib:/opt/sony/ebook/lib\"\n"
  "export PATH LD_LIBRARY_PATH\n";
  this.stringToFile("/tmp/script.sh", header+text);
  this.runScript();
}

//run a command and return the result
target.runCommandResult = function(text)
{
  var tmpf = "/tmp/__result__"
  this.runCommand(text+" >"+tmpf);
  var res = this.fileToString(tmpf);
  this.issue=res;
  FileSystem.deleteFile(tmpf);
  return res;
}

//DICTIONARY FUNCTIONS
target.init = function(){
	this.showHourGlass(false);
	this.loadDict();
	this.updateCursor(this.xCol, this.yCol);
}

target.exitApp = function(){
	this.saveDict();
	kbook.autoRunRoot.exitIf(kbook.model);
}


target.clearInput = function() {
	this.inputLine.setValue('');
}

target.clearStatus = function() {
	this.statusLine.setValue('');
}


target.clearLines = function() {
	this.printLines(new Array('','','','','','','','',''));
}

//shows/hides hourglass
target.showHourGlass = function(show) {
	this.hourGlass.show(true);
	this.hourGlass.changeLayout(230,undefined, undefined, 300, undefined, undefined);
	this.hourGlass.show(show);
};

//TODO: dynamic change of line font size according to # of lines in definition? (at least two sizes...)
target.printLines = function(aLines) {
	//all undefined lines will be cleared
	for(var i=0; i<9; i++) {
		if(!aLines[i]) aLines[i]='';
	}

	this.line1.setValue(aLines[0]);
	this.line2.setValue(aLines[1]);
	this.line3.setValue(aLines[2]);
	this.line4.setValue(aLines[3]);
	this.line5.setValue(aLines[4]);
	this.line6.setValue(aLines[5]);
	this.line7.setValue(aLines[6]);
	this.line8.setValue(aLines[7]);
	this.line9.setValue(aLines[8]);
}

//formats definition for Result area
target.txtFormat = function(def) {
	var aLines = new Array();
	var strPos = 0;
	var arrIdx = 0;
	var spaceIdx = 0;
	
	while(strPos+this.lineLength < def.length) {
		spaceIdx = strPos + def.slice(strPos, strPos+this.lineLength).lastIndexOf(' '); //find the last space before line break
		aLines[arrIdx++] = def.slice(strPos, spaceIdx);
		strPos = spaceIdx+1;
	}
	aLines[arrIdx] = def.slice(strPos, def.length); //last line...
	return aLines;
} 

//move cursor in columns (xCol: 0, 1 or 2)
target.moveCursor=function(direction) {
	if (direction=="left"){
		if (--this.xCol<0)
			this.xCol = 2;
	}
	if (direction=="right")	{
		if (++this.xCol>2)
			this.xCol = 0;
	}
	
	this.updateColCursor(this.xCol);
}

//redraw line cursor in a given field
target.updateLineCursor=function(xCol, yCol) {
	this.lineCursor.changeLayout(457+xCol*48,undefined, undefined, (yCol-1)*70-2, undefined, undefined);
}

//redraw column cursor in a given column
target.updateColCursor=function(xCol) {
	this.arrowCursorDown.changeLayout(457+xCol*48,undefined, undefined, 685, undefined, undefined);
	this.arrowCursorUp.changeLayout(457+xCol*48,undefined, undefined, -8, undefined, undefined);
}


target.arrowKey=function(button){
	if (button=="left"){
		//lookup previous dict. line
		this.findNeighbour(-1);
	}
	if (button=="right")	{
		//lookup next dict. line
		this.findNeighbour(1);
	}

	if (button=="up") {
	}

	if(button=="down") {
	}
}

//select a letter/function w/ function keys (key: 0..9)
target.pressDigit=function(digit){
	var button = this.keyMap[digit][this.xCol];
	var processed = false; //has the key been processed? ('catch all letters')

	if(button=='CD') {
		//change dictionary
		this.clearInput();
		this.clearLines();
		this.line2.setValue('Please enter name of the');
		this.line3.setValue('dictionary above: Not case-');
		this.line4.setValue('sensitive and w/o extension');
		this.line6.setValue("When ready, pres 'Enter'");
		this.dictChange = true;
		processed = true;
	}

	if(button=='BS') {
		//backspace
		var input = this.inputLine.getValue();
		this.inputLine.setValue(input.slice(0, input.length-1));
		processed = true;
	}

	if(button=='CLR') {
		//clear all text from inputLine
		processed = true;
		this.clearInput();
		this.clearLines();
	}

	if(!processed) {
		//letter
		this.inputLine.setValue(this.inputLine.getValue() + button);
	}

	//"0" key is the 10th line
	if(digit==0)
		this.yCol = 10;
	else
		this.yCol = digit;
		
	this.updateLineCursor(this.xCol, this.yCol);
}

target.getDict=function() {

	this.trace("Get dict: " + this.dictDir+ this.currDict);
	if (FileSystem.getFileInfo(this.dictDir + this.currDict)) {
		//get the max number of lines - removed atm, causes lag for large dictionaries
		//var res = this.runCommandResult('/usr/bin/wc -l ' + this.dictDir + this.currDict);
		//this.maxLinesNo = new Number(res.slice(0, res.lastIndexOf(' ')));
		this.lineNo = 1;
		this.statusLine.setValue("Dictionary "+this.currDict+" loaded."); // lines: " + this.maxLinesNo + ".");
	}
	else {
		this.clearLines();
		this.line8.setValue("Dictionary " + this.currDict +  " was not found")
		this.line9.setValue("Please press ''Choose Dictionary''");
		this.statusLine.setValue("No dictionary loaded!");
	}
}



target.searchTerm=function(term) {
	//this.showHourGlass(true);
	
	//I cannot access memory card from the shell (for the moment), so I have to have dictionary copied to internal memory
	var scriptLine = "/bin/grep -n -i '^" + term + "' " + this.dictDir + this.currDict + " | head -n 1";
	var res = this.runCommandResult(scriptLine);

	//this.showHourGlass(false);
	
	if(res != '') {
		try {
			//get leading line number (separated by colon)
			var colonIdx = res.indexOf(':');
			this.lineNo = Number(res.slice(0, colonIdx));
			//get term (separated by two spaces)
			var termIdx = res.search('  ');
			var term = res.slice(colonIdx+1, termIdx);
			//get defintion
			var definition = res.slice(termIdx+2, res.length-1);
			
			this.inputLine.setValue(term);
			this.printLines(this.txtFormat(definition));
			//TODO: store original searched term
		} catch(e) {
			this.statusLine.setValue("Exception catched while searching.");
		}
	} else {
		this.printLines(new Array('Word not found', 'Please try again'));
	}
	
}

//perform a search or load a new dictionary:
target.centerKey=function() {
	var input = this.inputLine.getValue();
	
	if(input=='') {
		this.clearLines();
		this.line2.setValue('Please type some text');
		this.line3.setValue('before pressing Enter.');
		return;
	}
		
	
	if(this.dictChange) {
		this.clearInput();
		this.clearLines();
		this.currDict = input + '.txt';
		this.getDict();
		this.dictChange = false;
	} else
		this.searchTerm(this.inputLine.getValue());
}

//previous/next line. offset = distance from original line
target.findNeighbour=function(offset) {
	var newLineNo = this.lineNo + offset;
	
	var scriptLine = "/bin/sed -n '" + newLineNo + "p' "  + this.dictDir + this.currDict;
	var res = this.runCommandResult(scriptLine);

	if(res=='') {
		//before first or after last line
		this.statusLine.setValue('No line found - end of dictionary?');
		return;
	}
	
	this.lineNo = newLineNo;
	var termIdx = res.search('  ');
	//get term (separated by two spaces)
	var term = res.slice(0, termIdx);
	//get defintion
	var definition = res.slice(termIdx+2, res.length-1);
	this.inputLine.setValue(term);
	this.printLines(this.txtFormat(definition));
}

target.saveDict=function() {
	var datPath = this.dictDir + this.datFile;
	
	try {
		if (FileSystem.getFileInfo(datPath))
			FileSystem.deleteFile(datPath);
		var stream = new Stream.File(datPath,1);
		stream.writeLine(this.currDict);
		stream.close();
	} catch(e){
		this.trace("Error writing .dat file.");	
		this.statusLine.setValue("Error writing .dat file.");
	}
}


target.loadDict = function() {
	var datPath = this.dictDir + this.datFile;
	var loadFailed = '';

	this.trace("Load Dat: " + datPath);
	try {
		var stream = new Stream.File(datPath);
		this.currDict = stream.readLine();
		stream.close();

		if (!FileSystem.getFileInfo(this.dictDir + this.currDict)) {
			loadFailed = this.currDict;	
		}

	} catch (e) {
		//failed to read from .dat file
		loadFailed = this.datFile;
	}

	if(loadFailed) {
		//datFile or dictionary was not found, reverting to the default dictionary
		this.line6.setValue("File " + loadFailed + " was not found."); 
		this.line7.setValue("reverting to default dictionary ''" + this.defaultDict + "''.");
		this.currDict = this.defaultDict;
	}

	this.getDict();
}

target.testFunction = function() {
/*	if (this.hg) {
		this.showHourGlass(false);
		this.hg = false;
	} else {
		this.showHourGlass(true);
		this.hg = true;
	}
	this.statusLine.setValue(this.hg);
*/
	this.statusLine.setValue("Changing variable...");
	this.setVariable("MY_VARIABLE", 76);
	var m = this.getVariable("MY_VARIABLE");
	this.statusLine.setValue("!"+ m +"!");

	try {
		this.timer = new Timer;
		this.timer.onCallback  = this.doQuitCallback;
		this.timer.device  = this.getDevice();
		this.timer.window  = this.container.getWindow();
		this.timer.schedule(2000);
	} catch(e) {
		this.trace("Catch: " + e);
	}
}

//GLOBALS
if (!target.hasOwnProperty('driveroot')) 
	target.driveroot = 'b:';

//dictionary files
target.dictDir = "/Data/database/media/dictionary/"; //directory with dictionaries
target.defaultDict = "dictionary.txt"; //default dictionary
target.currDict = target.defaultDict; //currently selected dictionary
target.datFile = "dict.dat"; //file where dictionary name is stored
target.lineNo = 0; //a line number with the result of the last search
target.maxLinesNo = 0; //# of lines in a current dictionary
target.dictChange = false; //are we in the process of dictionary change?

target.lineLength = 30; //length of line when displaying definition
target.xCol=1; //starting position of the cursor - at the middle column
target.yCol=10; //starting position of the cursor - at the 10th line ("0" key line)
target.enableLogging = false; //is logging enabled?
	
//map of special function keys
target.keyMap = new Array(
	new Array('CD','CLR','BS'),
	new Array('a','b','c'),
	new Array('d','e','f'),
	new Array('g','h','i'),
	new Array('j','k','l'),
	new Array('m','n','o'),
	new Array('p','q','r'),
	new Array('s','t','u'),
	new Array('v','w','x'),
	new Array('y','z',' ')
);

//target.hg = true;

target.init();

